/**
 * @author: Loy-winters1224@163.com
 * @date: 2014-9-4-下午4:55:44
 */
package net.loyintean.pearlshell.task.orientedgraph.task;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import net.loyintean.pearlshell.base.model.ILogInfo;
import net.loyintean.pearlshell.base.model.impl.LogInfoFactory;

import org.apache.log4j.Logger;

/**
 * node model of oriented graph.
 * 
 * @author Loy-winters1224@163.com
 * @version 2014-9-4.1.0.0
 */
public class TaskNode implements Runnable {

	/**
	 *
	 */
	private static final Logger LOGGER = Logger.getLogger(TaskNode.class);

	/**
	 * name
	 * 
	 */
	private String name;

	/**
	 * actrual executor of this task.
	 * 
	 */
	private TaskExecutor executor;

	/**
	 * arguments for executor.
	 * 
	 */
	private Object[] params;

	/**
	 * this task will wait until this latch be opened.
	 * 
	 */
	private CountDownLatch from;

	/**
	 * this task will try to open these latches.
	 * <p>
	 * init it as a LinkedList, because it will increase dynamic.
	 */
	private List<CountDownLatch> toList = new LinkedList<CountDownLatch>();

	/**
	 * init with name.
	 * 
	 * @author Loy-winters1224@163.com
	 * @param name
	 */
	public TaskNode(String name) {
		super();
		this.name = name;
	}

	/**
	 * 
	 * @author Loy-winters1224@163.com
	 * @see java.lang.Runnable#run()
	 * 
	 */
	@Override
	public final void run() {

		ILogInfo logInfo = LogInfoFactory.BUILD("name=" + name);

		LOGGER.info(logInfo.start());

		// 这里可能导致阻塞。
		try {
			from.await();
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}

		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug(logInfo.inner(" is executing!"));
		}

		executor.execute(params);

		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug(logInfo.inner(" is couting down!"));
		}

		for (CountDownLatch toLatch : toList) {
			toLatch.countDown();
		}

		LOGGER.info(logInfo.end(" is end!"));
	}

	/**
	 * add the param into {@link #toList};
	 * 
	 * @param to
	 */
	public void addTo(CountDownLatch to) {
		this.toList.add(to);
	}

	/**
	 * @return the {@link #name }
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the {@link #name }to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the {@link #from }
	 */
	public CountDownLatch getFrom() {
		return from;
	}

	/**
	 * @param from
	 *            the {@link #from }to set
	 */
	public void setFrom(CountDownLatch from) {
		this.from = from;
	}

	/**
	 * @param executor
	 *            the {@link #executor }to set
	 */
	public void setExecutor(TaskExecutor executor) {
		this.executor = executor;
	}

	/**
	 * @param params
	 *            the {@link #params }to set
	 */
	public void setParams(Object[] params) {
		this.params = params;
	}

	/**
	 * 
	 * @author Loy-winters1224@163.com
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("TaskNode [");
		if (name != null) {
			builder.append("name=");
			builder.append(name);
			builder.append(", ");
		}
		if (executor != null) {
			builder.append("executor=");
			builder.append(executor);
			builder.append(", ");
		}
		if (params != null) {
			builder.append("params=");
			builder.append(Arrays.toString(params));
			builder.append(", ");
		}
		if (from != null) {
			builder.append("from=");
			builder.append(from);
			builder.append(", ");
		}
		if (toList != null) {
			builder.append("toList=");
			builder.append(toList);
		}
		builder.append("]");
		return builder.toString();
	}
}
